using System;
using System.Xml;
using System.Collections;
using System.Runtime.InteropServices;

namespace Scenario.Modules.PCM.DataModel.ConfigurationManager.Property
{
	//*********************************************************************
	//
	// XMLProperties Class
	//
	// The XMLProperties class represents a collection base of XMLGroupProperties
	// Its imports methods from WAPI.XmlObjectSet like get set and add
	// XMLProperties Has no fields
	//
	//*********************************************************************
	public class XMLProperties : bOS.XML.Data.XMLObjectSet 
	{
		public const string MAIN_NODE	= "Properties";

		public XMLProperties()
		{
			this.Init();
		}

		public XMLProperties(System.Xml.XmlNode node)
		{
			this.Parse(node);
		}

		override public void Init()
		{
			this.RemoveAll();

		}

		override public void Parse(System.Xml.XmlNode node2Parse)
		{
			this.Init();

			System.Xml.XmlNode node;

			for ( int i=0; i<node2Parse.ChildNodes.Count;i++)
			{
				node = node2Parse.ChildNodes[i];

				switch ( node.Name) 
				{
					case XMLPropertiesGroup.MAIN_NODE:
						this.Add ( new XMLPropertiesGroup(node));
						break;
				}
			}

		}

		new public XMLPropertiesGroup this[ int index ]  
		{
			get  
			{
				return( (XMLPropertiesGroup) List[index] );
			}
			set  
			{
				List[index] = value;
			}
		}

		

		override public bOS.XML.XMLNode GetXMLNode()
		{
			bOS.XML.XMLNode xmlNode = new bOS.XML.XMLNode(XMLProperties.MAIN_NODE);

			for ( int i=0; i<this.List.Count;i++)
			{
				XMLPropertiesGroup group = this[i];
				xmlNode.AddNode ( group.GetXMLNode() );
			}

			return xmlNode;
		}

		private string GetTest()
		{
			string Test;
			Test = "<Properties>";
			Test +=	"<Properties Group=\"Family1\">";
			Test +=	"<Property Name=\"Name1\" Type=\"Type1\">";
			Test +=	"<Description>Descript prperty Name1</Description>";
			Test +=	"<Values>";
			Test +=	"<Value>1</Value>";
			Test +=	"<Value>2</Value>";
			Test +=	"</Values>";
			Test +=	"</Property>";
			Test +=	"</Properties>";
			Test +=	"<Properties Group=\"Family2\">";
			Test +=	"<Property Name=\"Name21\" Type=\"Type21\">";
			Test +=	"<Description>Descript prperty Name2</Description>";
			Test +=	"<Values>";
			Test +=	"<Value>11</Value>";
			Test +=	"<Value>22</Value>";
			Test +=	"<Value>33</Value>";
			Test +=	"</Values>";
			Test +=	"</Property>";
			Test +=	"<Property Name=\"Rule\" Type=\"RetrivingRule\">";
			Test +=	"<Description>Descript prperty Name2</Description>";
			Test +=	"<Values>";
			Test +=	"</Values>";
			Test +=	"</Property>";
			Test +=	"</Properties>";
			Test +=	"</Properties>";

			return Test;
		}

		/** Method for return a groupproperties from collection **/
		public XMLPropertiesGroup Get(string sGroup)
		{
			XMLPropertiesGroup groupProperty;

			for ( int i=0; i<this.Count; i++)
			{
				
				groupProperty = this[i];
				if ( groupProperty.sGroup == sGroup )
				{
					return groupProperty;
				}
				
			}
			
			throw new Exception.GroupPropertiesNotFound(sGroup + " not found.");
		}

		public bool AlmostIn(XMLProperties vValues)
		{
			XMLPropertiesGroup leftProperty;
			XMLPropertiesGroup rightProperty;

			for ( int i=0; i<this.Count; i++)
			{
				leftProperty = this[i];

				try
				{
					rightProperty = vValues.Get(leftProperty.sGroup);
				}
				catch ( Exception.GroupPropertiesNotFound)
				{
					return false;
				}
			}
			
			return true;
		}

		public bool CheckValue(string sPropertyGroup, string sPropertyName, string sValue)
		{
			try
			{
				XMLPropertiesGroup group = this.Get (sPropertyGroup);
				XMLProperty property = group.Get (sPropertyName);
				XMLPropertyValue propValue = (XMLPropertyValue)property.XMLPropertyValues[0];

				if ( propValue.Value.CompareTo (sValue) == 0 )
					return true;

				return false;
			}
			catch 
			{
				return false;
			}
		}

		public bool AlmostInByName (string sGroup)
		{
			XMLPropertiesGroup PropertiesGroup;

			for ( int i=0; i<this.Count; i++)
			{
				PropertiesGroup = this[i];

				if (PropertiesGroup.Group == sGroup)
				{
					return true;
				}
			}
			
			return false;
		}

		public bool RemoveByName(string sGroup)
		{
			XMLPropertiesGroup PropertiesGroup;

			for ( int i=0; i<this.Count; i++)
			{
				PropertiesGroup = this[i];

				if (PropertiesGroup.sGroup == sGroup)
				{
					this.RemoveAt (i);
					return true;
				}
			}
			
			return false;
		}

		/** Method for filling the Properties widthout calling WAPI first **/
		public void ReadFromConfiguration()
		{
			String sProperties= string.Empty;

#if _PCM_TEST_
			sProperties = GetTest();
#else
			Scenario.Modules.PCM.DataModel.ConfigurationManager.PCMWAPIResponse response = new Scenario.Modules.PCM.DataModel.ConfigurationManager.PCMWAPIResponse();
			sProperties = XMLProperties.GetProperties (ref response);
			if ( response.iCode != 0 )
			{
				throw new Exception.ConfigurationError ( response.sMsg);
			}
#endif
			this.Parse (sProperties);
		}

		[ DllImport( "ConfigurationManager.dll", EntryPoint="GetProperties")]
		public static extern string GetProperties(ref Scenario.Modules.PCM.DataModel.ConfigurationManager.PCMWAPIResponse response);

		/** SORTING  FIELDS **/

		public enum SortFields 
		{
			Group
		}

		/** SORTING METHODS **/


		public void Sort(SortFields sortField, bool isAscending) 
		{
			switch (sortField) 
			{
				case SortFields.Group:
					InnerList.Sort(new GroupComparer());
					break;
				
			}
			if (!isAscending) InnerList.Reverse();
		}


		private sealed class GroupComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLPropertiesGroup first = (XMLPropertiesGroup) x;
				XMLPropertiesGroup second = (XMLPropertiesGroup) y;
				return first.Group.CompareTo(second.Group);
			}
		}


	}
}